home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / lang / PPCSmllEiffel.lha / PPCSmallEiffel / lib_se / parent_list.e < prev    next >
Text File  |  1998-01-16  |  12KB  |  636 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  4. --                       http://www.loria.fr/SmallEiffel
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it 
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later 
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License 
  11. -- for  more  details.  You  should  have  received a copy of the GNU General 
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class PARENT_LIST
  17.    -- 
  18.    -- To store the parent list of a class.
  19.    -- 
  20.  
  21. inherit GLOBALS;
  22.  
  23. creation make
  24.    
  25. feature 
  26.    
  27.    base_class: BASE_CLASS;
  28.      -- Where the parent list is written.
  29.       
  30.    start_position: POSITION;
  31.      -- Of the keyword "inherit".
  32.    
  33.    heading_comment: COMMENT;
  34.      -- Global comment of the inherit clause.
  35.    
  36. feature {NONE}
  37.    
  38.    list: ARRAY[PARENT];
  39.       
  40. feature 
  41.    
  42.    make(bc: like base_class; sp: like start_position; 
  43.     hc: like heading_comment; l: like list) is
  44.       require
  45.      bc /= Void;
  46.      sp /= Void;
  47.      l.lower = 1 and not l.empty;
  48.       do
  49.      base_class := bc;
  50.      heading_comment := hc;
  51.      start_position := sp;
  52.      list := l;
  53.       ensure
  54.      base_class = bc;
  55.      start_position = sp;
  56.      heading_comment = hc;
  57.      list = l;
  58.       end;
  59.    
  60.    count: INTEGER is
  61.       do
  62.      Result := list.upper;
  63.       end;
  64.    
  65.    up_to_any_in(pl: FIXED_ARRAY[BASE_CLASS]) is
  66.       local
  67.      i: INTEGER;
  68.      p: PARENT;
  69.      bc: BASE_CLASS;
  70.       do
  71.      from  
  72.         i := list.upper;
  73.      until
  74.         i = 0 
  75.      loop
  76.         p := list.item(i);
  77.         bc := p.type.base_class;
  78.         if not pl.fast_has(bc) then
  79.            pl.add_last(bc);
  80.         end;
  81.         i := i - 1;
  82.      end;
  83.      from  
  84.         i := list.upper;
  85.      until
  86.         i = 0 
  87.      loop
  88.         p := list.item(i);
  89.         bc := p.type.base_class;
  90.         if bc /= class_any then
  91.            bc.up_to_any_in(pl);
  92.         end;
  93.         i := i - 1;
  94.      end;
  95.       end;
  96.  
  97.    base_class_name: CLASS_NAME is
  98.       do
  99.      Result := base_class.base_class_name;
  100.       end;
  101.    
  102.    has_redefine(fn: FEATURE_NAME): BOOLEAN is
  103.       require
  104.      fn /= Void
  105.       local
  106.      i: INTEGER;
  107.       do
  108.      from  
  109.         i := 1;
  110.      until
  111.         Result or else i > list.upper
  112.      loop
  113.         Result := list.item(i).has_redefine(fn); 
  114.         i := i + 1;
  115.      end;
  116.       end;
  117.    
  118.    super: PARENT is
  119.       require
  120.      count = 1
  121.       do
  122.      Result := list.first;
  123.       end;
  124.  
  125. feature {TYPE}
  126.  
  127.    smallest_ancestor(ctx: TYPE): TYPE is
  128.       require
  129.      ctx.is_run_type;
  130.       local
  131.      i: INTEGER;
  132.      p: PARENT;
  133.      sa: TYPE;
  134.       do
  135.      from  
  136.         i := list.upper;
  137.      until
  138.         i = 0
  139.      loop
  140.         p := list.item(i);
  141.         sa := p.smallest_ancestor(ctx).run_type;
  142.         if Result = Void then
  143.            Result := sa;
  144.         else
  145.            Result := sa.smallest_ancestor(Result);
  146.         end;
  147.         if Result.is_any then
  148.            i := 0;
  149.         else
  150.            i := i - 1;
  151.         end;
  152.      end;
  153.       ensure
  154.      Result.is_run_type;
  155.       end;
  156.  
  157. feature {BASE_CLASS}
  158.    
  159.    up_to_original(bottom: BASE_CLASS; top_fn: FEATURE_NAME): FEATURE_NAME is
  160.       local
  161.      p1, p2: PARENT;
  162.      fn1, fn2, new_fn: FEATURE_NAME;
  163.      i: INTEGER;
  164.       do
  165.      from
  166.         i := list.upper;
  167.      until
  168.         i = 0 or else fn1 /= Void
  169.      loop
  170.         p1 := list.item(i);
  171.         fn1 := p1.up_to_original(bottom,top_fn);
  172.         i := i - 1;
  173.      end;
  174.      from
  175.      until
  176.         i = 0 
  177.      loop
  178.         p2 := list.item(i);
  179.         fn2 := p2.up_to_original(bottom,top_fn);
  180.         if fn2 /= Void then
  181.            new_fn := p2.do_rename(top_fn);
  182.            if p2.has_select_for(new_fn) then
  183.           p1 := p2;
  184.           fn1 := fn2;
  185.            end;
  186.         end;
  187.         i := i - 1;
  188.      end;
  189.      if fn1 /= Void then
  190.         if fn1.to_string /= top_fn.to_string then
  191.            Result := repeated_inheritance(p1,fn1,top_fn);
  192.         else
  193.            Result := fn1;
  194.         end;
  195.      end;
  196.       end;
  197.  
  198.    clients_for(fn: FEATURE_NAME): CLIENT_LIST is
  199.       require
  200.      fn /= Void
  201.       local
  202.      i: INTEGER;
  203.      cl: CLIENT_LIST;
  204.       do
  205.      from  
  206.         i := list.upper;
  207.      until
  208.         i = 0
  209.      loop
  210.         cl := list.item(i).clients_for(fn); 
  211.         if Result = Void then
  212.            Result := cl;
  213.         elseif cl /= Void then
  214.            Result := Result.append(cl);
  215.         end;
  216.         if Result /= Void and then Result.gives_permission_to_any then
  217.            i := 0;
  218.         else
  219.            i := i - 1;
  220.         end;
  221.      end;
  222.       ensure
  223.      Result /= Void
  224.       end;
  225.  
  226.    going_up(trace: FIXED_ARRAY[PARENT]; top: BASE_CLASS; 
  227.         top_fn: FEATURE_NAME;): FEATURE_NAME is
  228.       require
  229.      top /= Void;
  230.      top_fn /= Void
  231.       local
  232.      i: INTEGER;
  233.      p1, p2: PARENT;
  234.      fn1, fn2: FEATURE_NAME;
  235.       do
  236.      from
  237.         i := list.upper;
  238.      until
  239.         fn1 /= Void or else i = 0
  240.      loop
  241.         p1 := list.item(i);
  242.         fn1 := p1.going_up(trace,top,top_fn);
  243.         i := i - 1;
  244.      end;
  245.      from
  246.      until
  247.         i = 0
  248.      loop
  249.         p2 := list.item(i);
  250.         fn2 := p2.going_up(trace,top,top_fn);
  251.         if fn2 /= Void then
  252.            if p2.has_select_for(fn2) then
  253.           p1 := p2;
  254.           fn1 := fn2;
  255.            end;
  256.         end;
  257.         i := i - 1;
  258.      end;
  259.      Result := fn1;
  260.       end;
  261.  
  262.    is_a_vncg(t1, t2: TYPE): BOOLEAN is
  263.       require
  264.      t1.run_type = t1;
  265.      t2.run_type = t2;
  266.      t2.generic_list /= Void;
  267.      eh.empty
  268.       local
  269.      i: INTEGER;
  270.       do
  271.      from
  272.         i := list.upper;
  273.      until
  274.         Result or else i = 0
  275.      loop
  276.         Result := list.item(i).is_a_vncg(t1,t2);
  277.         i := i - 1;
  278.      end;
  279.       ensure
  280.      eh.empty
  281.       end;
  282.  
  283.    has(fn: FEATURE_NAME): BOOLEAN is
  284.       local
  285.      i: INTEGER;
  286.       do
  287.      from
  288.         i := list.upper;
  289.      until
  290.         Result or else i = 0
  291.      loop
  292.         Result := list.item(i).has(fn);
  293.         i := i - 1;
  294.      end;
  295.       end;
  296.    
  297.    collect_invariant(rc: RUN_CLASS) is
  298.       require
  299.      rc /= Void
  300.       local
  301.      i: INTEGER;
  302.       do
  303.      from
  304.         i := list.upper;
  305.      until
  306.         i = 0
  307.      loop
  308.         list.item(i).type.base_class.collect_invariant(rc);
  309.         i := i - 1;
  310.      end;
  311.       end;
  312.    
  313.    inherit_cycle_check is
  314.       local
  315.      i: INTEGER;
  316.      p: PARENT;
  317.      bc: BASE_CLASS;
  318.       do
  319.      from  
  320.         i := list.upper;
  321.      until
  322.         i = 0
  323.      loop
  324.         p := list.item(i);
  325.         bc := p.type.base_class;
  326.         if bc = Void then
  327.            eh.add_position(p.start_position);
  328.            fatal_error(fz_cnf);
  329.         else
  330.            bc.inherit_cycle_check;
  331.         end;
  332.         i := i - 1;
  333.      end;
  334.       end;
  335.  
  336.    has_parent(c: BASE_CLASS): BOOLEAN is
  337.       require
  338.      not c.is_any
  339.       local
  340.      i: INTEGER;
  341.      bc: BASE_CLASS;
  342.       do
  343.      from  
  344.         i := list.upper;
  345.      until
  346.         i = 0
  347.      loop
  348.         bc := list.item(i).type.base_class;
  349.         if c = bc then
  350.            Result := true;
  351.            i := 0;
  352.         elseif bc.is_subclass_of_aux(c) then
  353.            Result := true;
  354.            i := 0;
  355.         else
  356.            i := i - 1;
  357.         end;
  358.      end;
  359.       end;
  360.  
  361. feature {BASE_CLASS}
  362.    
  363.    first_parent_for(c: BASE_CLASS): PARENT is
  364.      -- Gives the first parent going to `c'.
  365.       local
  366.      i: INTEGER;
  367.      pbc: BASE_CLASS;
  368.       do
  369.      from  
  370.         i := 1;
  371.      until
  372.         Result /= Void
  373.      loop
  374.         Result := list.item(i);
  375.         pbc := Result.type.base_class;
  376.         if pbc = c then
  377.         elseif pbc.is_subclass_of(c) then
  378.         else
  379.            Result := Void;
  380.         end;
  381.         i := i + 1;
  382.      end;
  383.       ensure
  384.      Result /= Void
  385.       end;
  386.    
  387.    next_parent_for(c: BASE_CLASS; previous: PARENT): like previous is
  388.      -- Gives the next one or Void.
  389.       local
  390.      i: INTEGER;
  391.      pbc: BASE_CLASS;
  392.       do
  393.      from  
  394.         from
  395.            i := 1;
  396.         until
  397.            Result = previous
  398.         loop
  399.            Result := list.item(i);
  400.            i := i + 1;
  401.         end;
  402.         Result := Void;
  403.      until
  404.         Result /= Void or else i > list.count
  405.      loop
  406.         Result := list.item(i);
  407.         pbc := Result.type.base_class;
  408.         if pbc = c then
  409.         elseif pbc.is_subclass_of(c) then
  410.         else
  411.            Result := Void;
  412.         end;
  413.         i := i + 1;
  414.      end;
  415.       end;
  416.  
  417. feature {BASE_CLASS}
  418.  
  419.    header_comment_for(ci: CLASS_INVARIANT) is
  420.       local
  421.      i: INTEGER;
  422.       do
  423.      from
  424.         i := list.upper;
  425.